import type { Instruction } from '@/types/AIResponse'
import Graphic from '@arcgis/core/Graphic'
import * as geometryEngine from '@arcgis/core/geometry/geometryEngine.js'
import SimpleMarkerSymbol from '@arcgis/core/symbols/SimpleMarkerSymbol'
import SimpleLineSymbol from '@arcgis/core/symbols/SimpleLineSymbol'
import SimpleFillSymbol from '@arcgis/core/symbols/SimpleFillSymbol'
import SketchViewModel from '@arcgis/core/widgets/Sketch/SketchViewModel'
import { ElMessage } from 'element-plus'
import { showLayer } from './mapLayers'
import * as echarts from 'echarts'

// 处理测量距离
export const handleMeasureDistance = async (
  instruction: Instruction,
  view: __esri.MapView,
): Promise<void> => {
  return new Promise(async (resolve, reject) => {
    try {
      ElMessage.success('请在地图上点击起点，然后点击终点或多个点，双击完成测量')

      // 创建临时的SketchViewModel用于绘制测量线
      const sketchVM = new SketchViewModel({
        view: view,
        layer: showLayer,
        pointSymbol: new SimpleMarkerSymbol({
          color: [255, 0, 0],
          size: 8,
          outline: {
            color: [255, 255, 255],
            width: 1,
          },
        }),
        polylineSymbol: new SimpleLineSymbol({
          color: [0, 0, 255],
          width: 2,
        }),
      })

      // 监听绘制完成事件
      const createHandler = async (event: __esri.SketchViewModelCreateEvent) => {
        if (event.state === 'complete' && event.graphic.geometry!.type === 'polyline') {
          sketchVM.destroy()

          // 计算距离
          const polyline = event.graphic.geometry as __esri.Polyline
          const unit = instruction.params.measureDistanceParams?.unit || 'meters'
          const distance = geometryEngine.geodesicLength(polyline, unit as __esri.LinearUnits)

          // 显示距离信息
          const formattedDistance =
            unit === 'kilometers' ? `${distance.toFixed(2)} 公里` : `${distance.toFixed(2)} 米`

          // 在线的中点添加标注
          const midPoint = polyline.getPoint(0, Math.floor(polyline.paths[0].length / 2))

          const textSymbol = {
            type: 'text',
            color: [0, 0, 0],
            haloColor: [255, 255, 255],
            haloSize: 1,
            text: formattedDistance,
            xoffset: 0,
            yoffset: -15,
            font: {
              size: 12,
              family: 'sans-serif',
              weight: 'bold',
            },
          }

          const labelGraphic = new Graphic({
            geometry: midPoint,
            symbol: textSymbol as any,
          })

          showLayer.add(labelGraphic)
          ElMessage.success(`测量完成: ${formattedDistance}`)
          resolve()
        }
      }

      sketchVM.on('create', createHandler)
      sketchVM.create('polyline')
    } catch (error) {
      ElMessage.error(`测量距离失败: ${error}`)
      reject(error)
    }
  })
}

// 处理测量面积
export const handleMeasureArea = async (
  instruction: Instruction,
  view: __esri.MapView,
): Promise<void> => {
  return new Promise(async (resolve, reject) => {
    try {
      ElMessage.success('请在地图上绘制区域，双击完成测量')

      // 创建临时的SketchViewModel用于绘制测量区域
      const sketchVM = new SketchViewModel({
        view: view,
        layer: showLayer,
        polygonSymbol: new SimpleFillSymbol({
          color: [0, 0, 255, 0.2],
          outline: {
            color: [0, 0, 255],
            width: 2,
          },
        }),
      })

      // 监听绘制完成事件
      const createHandler = async (event: __esri.SketchViewModelCreateEvent) => {
        if (event.state === 'complete' && event.graphic.geometry!.type === 'polygon') {
          sketchVM.destroy()

          // 计算面积
          const polygon = event.graphic.geometry as __esri.Polygon
          const unit = instruction.params.measureAreaParams?.unit || 'square-meters'
          const area = geometryEngine.geodesicArea(polygon, unit as __esri.AreaUnits)

          // 显示面积信息
          let formattedArea = ''
          if (unit === 'square-kilometers') {
            formattedArea = `${area.toFixed(2)} 平方公里`
          } else if (unit === 'hectares') {
            formattedArea = `${area.toFixed(2)} 公顷`
          } else {
            formattedArea = `${area.toFixed(2)} 平方米`
          }

          // 在多边形中心添加标注
          const centroid = polygon.centroid

          const textSymbol = {
            type: 'text',
            color: [0, 0, 0],
            haloColor: [255, 255, 255],
            haloSize: 1,
            text: formattedArea,
            font: {
              size: 12,
              family: 'sans-serif',
              weight: 'bold',
            },
          }

          const labelGraphic = new Graphic({
            geometry: centroid,
            symbol: textSymbol as any,
          })

          showLayer.add(labelGraphic)
          ElMessage.success(`测量完成: ${formattedArea}`)
          resolve()
        }
      }

      sketchVM.on('create', createHandler)
      sketchVM.create('polygon')
    } catch (error) {
      ElMessage.error(`测量面积失败: ${error}`)
      reject(error)
    }
  })
}

// 处理热力图生成
export const handleHeatmapGeneration = async (
  instruction: Instruction,
  view: __esri.MapView,
): Promise<void> => {
  return new Promise(async (resolve, reject) => {
    try {
      ElMessage.success('正在生成热力图，请稍候...')

      // 获取点图层数据
      const pointLayer = view.map.allLayers.find(
        (layer) =>
          layer.type === 'feature' && (layer as __esri.FeatureLayer).geometryType === 'point',
      ) as __esri.FeatureLayer

      if (!pointLayer) {
        ElMessage.warning('未找到点图层，无法生成热力图')
        reject(new Error('未找到点图层'))
        return
      }

      // 查询所有点
      const pointFeatures = await pointLayer.queryFeatures({
        where: '1=1',
        outFields: ['*'],
        returnGeometry: true,
      })

      if (pointFeatures.features.length === 0) {
        ElMessage.warning('点图层中没有数据，无法生成热力图')
        reject(new Error('点图层中没有数据'))
        return
      }

      // 创建热力图图层
      // 注意：这里使用简化的方式模拟热力图效果
      // 实际项目中可以使用ArcGIS的HeatmapRenderer或第三方热力图库
      const heatmapParams = instruction.params.heatmapParams || {}
      const radius = heatmapParams.radius || 10
      const blur = heatmapParams.blur || 0.85
      const gradient = heatmapParams.gradient || ['blue', 'purple', 'red']

      // 为每个点创建一个带透明度的圆形
      pointFeatures.features.forEach((feature) => {
        const point = feature.geometry as __esri.Point

        const heatPoint = new Graphic({
          geometry: point,
          symbol: new SimpleMarkerSymbol({
            color: gradient[gradient.length - 1],
            size: radius * 2,
            outline: {
              color: [0, 0, 0, 0],
              width: 0,
            },
          }),
        })

        showLayer.add(heatPoint)
      })

      ElMessage.success(`热力图生成完成，共包含 ${pointFeatures.features.length} 个点`)
      resolve()
    } catch (error) {
      ElMessage.error(`热力图生成失败: ${error}`)
      reject(error)
    }
  })
}

// 处理报表生成
export const handleGenerateReport = async (
  instruction: Instruction,
  view: __esri.MapView,
  setAttributes: (attrs: any) => void,
  setDialogTitle: (title: string) => void,
  setDialogVisible: (visible: boolean) => void,
): Promise<void> => {
  return new Promise(async (resolve, reject) => {
    try {
      ElMessage.success('正在生成报表，请稍候...')

      const reportParams = instruction.params.reportParams
      if (!reportParams) {
        ElMessage.error('缺少报表参数')
        reject(new Error('缺少报表参数'))
        return
      }

      // 获取图层数据
      let targetLayer: __esri.FeatureLayer | undefined

      // 根据分组字段确定目标图层
      const groupByField = reportParams.groupBy || ''
      if (groupByField.includes('Building')) {
        // 查找点图层
        targetLayer = view.map.allLayers.find(
          (layer) =>
            layer.type === 'feature' && (layer as __esri.FeatureLayer).geometryType === 'point',
        ) as __esri.FeatureLayer
      } else if (groupByField.includes('Road')) {
        // 查找线图层
        targetLayer = view.map.allLayers.find(
          (layer) =>
            layer.type === 'feature' && (layer as __esri.FeatureLayer).geometryType === 'polyline',
        ) as __esri.FeatureLayer
      } else if (groupByField.includes('Area') || groupByField.includes('Service')) {
        // 查找面图层
        targetLayer = view.map.allLayers.find(
          (layer) =>
            layer.type === 'feature' && (layer as __esri.FeatureLayer).geometryType === 'polygon',
        ) as __esri.FeatureLayer
      }

      if (!targetLayer) {
        ElMessage.warning('未找到合适的图层，无法生成报表')
        reject(new Error('未找到合适的图层'))
        return
      }

      // 查询数据
      const condition = reportParams.condition || '1=1'
      const features = await targetLayer.queryFeatures({
        where: condition,
        outFields: ['*'],
        returnGeometry: false,
      })

      if (features.features.length === 0) {
        ElMessage.warning('未找到符合条件的数据，无法生成报表')
        reject(new Error('未找到符合条件的数据'))
        return
      }

      // 处理数据，按分组字段统计
      const groupData: Record<string, number> = {}
      features.features.forEach((feature) => {
        const groupValue = feature.attributes[groupByField] || '未分类'
        if (groupData[groupValue]) {
          groupData[groupValue]++
        } else {
          groupData[groupValue] = 1
        }
      })

      // 准备ECharts数据
      const chartData = {
        title: reportParams.title,
        chartType: reportParams.chartType,
        data: Object.entries(groupData).map(([name, value]) => ({ name, value })),
      }

      // 将图表数据传递给对话框显示
      setAttributes(chartData)
      setDialogTitle(`报表: ${reportParams.title}`)
      setDialogVisible(true)

      ElMessage.success('报表生成完成')
      resolve()
    } catch (error) {
      ElMessage.error(`报表生成失败: ${error}`)
      reject(error)
    }
  })
}
